package io.gitee.jinceon.pmd.rules;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.java.ast.ASTImplementsList;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTPackageDeclaration;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;

import java.util.concurrent.atomic.AtomicBoolean;


public class CurrentUserRule extends AbstractJavaRule {
    private ASTImportDeclaration errorNode = null;
    private boolean not_in_controller = false;
    private boolean has_import_httpRequestHandler = false;

    /**
     * 包名不含 .controller
     */
    @Override
    public Object visit(ASTPackageDeclaration node, Object data) {
        if(!node.getName().endsWith(".controller")){
            not_in_controller = true;
        }
        return null;
    }

    /**
     * 引入了HttpRequestHandler
     */
    @Override
    public Object visit(ASTImportDeclaration node, Object data) {
        if(!not_in_controller)return null;
        if(node.getImportedName().equals("com.lightning.config.HttpRequestHandler")){
            has_import_httpRequestHandler = true;
            errorNode = node;
        }
        return null;
    }

    /**
     * 例外情况: MetaObjectHandler实现Mybatis统一插入创建人、更新人，需要获取当前用户，忽略不报错
     */
    @Override
    public Object visit(ASTImplementsList node, Object data){
        if(!has_import_httpRequestHandler)return null;
        AtomicBoolean implOfMetaObjectHandler = new AtomicBoolean(false);
        node.iterator().forEachRemaining(i->{
            implOfMetaObjectHandler.set(implOfMetaObjectHandler.get()
                    || i.getTypeDefinition().getType().getName()
                    .equals("com.baomidou.mybatisplus.core.handlers.MetaObjectHandler"));
        });
        if(!implOfMetaObjectHandler.get()){
            asCtx(data).addViolation(errorNode);
        }
        return null;
    }

    @Override
    public void end(RuleContext ctx) {
        not_in_controller = false;
        has_import_httpRequestHandler = false;
        errorNode = null;
        super.end(ctx);
    }

}
